package com.me.mygdxgame.controller;

import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.InputProcessorQueue;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.maps.MapLayer;
import com.badlogic.gdx.maps.MapObject;
import com.badlogic.gdx.maps.objects.PolylineMapObject;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.box2d.World;
import com.me.mygdxgame.LevelTile;
import com.me.mygdxgame.assets.Assets;
import com.me.mygdxgame.models.BoxBuilder;
import com.me.mygdxgame.models.Player;
import com.me.mygdxgame.screens.MenuScreen;
import com.me.mygdxgame.util.CameraHelper;
import com.me.mygdxgame.util.Constants;
import com.me.mygdxgame.view.WorldRenderer;

public class WorldController extends InputAdapter{

	public static final String TAG = WorldController.class.getName();
	public CameraHelper cameraHelper;
	public LevelTile level;
	public int lives;
	public int score;
	public World b2dworld;
	public Player player;
	private Game game;
	private Vector3 touchPoint;
	private Rectangle moveLeft, moveRight, moveJump;
	private boolean isMoveLeft, isMoveRight, isJump;

	public WorldController(Game game) {
		this.game = game;
		init();
	}

	private void init() {
		Gdx.input.setInputProcessor(this);
		cameraHelper = new CameraHelper();
		lives = Constants.LIVES_START;
		touchPoint = new Vector3();
		moveLeft = new Rectangle(30, 10, 100, 100);
		moveRight = new Rectangle(200, 10, 100, 100);
		moveJump = new Rectangle(1020, 30, 100, 100);
		initLevel();

	}

	private void initLevel() {
		score = 0;
		level = new LevelTile(Constants.LEVEL_01);
		initPhysics();
	}

	private void initPhysics() {
		b2dworld = new World(new Vector2(0, -9.81f), true);
		Vector2 orgin = new Vector2();

		player = new Player(b2dworld);
		cameraHelper.setTarget(player);

		MapLayer groundLayer = level.map.getLayers().get("ground");
		for (int i = 0; i < groundLayer.getObjects().getCount(); i++) {
			MapObject obj = groundLayer.getObjects().get(i);
			PolylineMapObject poly = (PolylineMapObject) obj;
			// poly.getPolyline().getVertices()

			BoxBuilder.CreateGroundBody(b2dworld, poly);

			// PolygonShape groundPoly = new PolygonShape();
			// groundPoly.set(poly.getPolyline().getVertices());
			// BodyDef groundBodyDef = new BodyDef();
			// groundBodyDef.type = BodyType.StaticBody;
			// groundBody = b2dworld.createBody(groundBodyDef);
			// FixtureDef fixtureDef = new FixtureDef();
			// fixtureDef.shape = groundPoly;
			// fixtureDef.filter.groupIndex = 0;
			// groundBody.createFixture(fixtureDef);
			// groundPoly.dispose();

		}
		
		
		for(int i = 0; i < level.stones.size; i++){
			Sprite tempSprite = level.stones.get(i).sprite;
			BoxBuilder.CreateStoneBody(b2dworld, tempSprite.getX() + 20, tempSprite.getY() + 20);
		}
		
		for(int i = 0; i < level.items.size; i++){
			Sprite tempSprite = level.items.get(i).sprite;
			BoxBuilder.CreateStoneBody(b2dworld, tempSprite.getX() + 20, tempSprite.getY() + 20);
		}
	}

	public void update(float deltaTime) {
		handleDebugInput(deltaTime);
		handleInputGame(deltaTime);
		b2dworld.step(1 / 60f, 8, 3);
		level.update(deltaTime);
		player.update(deltaTime);
		cameraHelper.update(deltaTime);
	}

	private void handleDebugInput(float deltaTime) {
		if (!cameraHelper.hasTarget(player)) {
			if (Gdx.app.getType() != ApplicationType.Desktop)
				return;

			float camMoveSpeed = 500 * deltaTime;
			if (Gdx.input.isKeyPressed(Keys.LEFT))
				moveCamera(-camMoveSpeed, 0);
			if (Gdx.input.isKeyPressed(Keys.RIGHT))
				moveCamera(camMoveSpeed, 0);
//			if (Gdx.input.isKeyPressed(Keys.SPACE))
//				cameraHelper.setPosition(WorldRenderer.positionInitCamera.x,
//						WorldRenderer.positionInitCamera.y);
		}

	}

	@Override
	public boolean keyDown(int keycode) {
		return false;
	}

	@Override
	public boolean keyUp(int keycode) {
		if(keycode == Keys.ENTER){
			cameraHelper.setTarget(cameraHelper.hasTarget()?
					null : player);
		}else if(keycode == Keys.ESCAPE || keycode == Keys.BACK){
			backToMenu();
		}
		return false;
	}

	private void moveCamera(float x, float y) {
		x += cameraHelper.getPosition().x;
		y += cameraHelper.getPosition().y;
		cameraHelper.setPosition(x, y);

	}
	
	private void handleInputGame(float deltaTime){
		if(cameraHelper.hasTarget(player)){
			if(Gdx.input.isKeyPressed(Keys.LEFT) || isMoveLeft){
				player.velocity.x = - player.terminalVelocity.x;
				player.body.setLinearVelocity(-2, player.body.getLinearVelocity().y);
//				player.body.setTransform(-1f, 0f, (float)(MathUtils.degreesToRadians*Math.PI/2));
			}else if(Gdx.input.isKeyPressed(Keys.RIGHT) || isMoveRight){
				player.velocity.x = player.terminalVelocity.x;
				player.body.setLinearVelocity(5, player.body.getLinearVelocity().y);
//				player.body.setTransform(1, 0, 0);
			}
			
			if(Gdx.input.isKeyPressed(Keys.SPACE) || isJump){
				player.setJumping(true);
			}else if(!isJump){
				player.setJumping(false);
			}
		}
	}
	
	private void backToMenu(){
		game.setScreen(new MenuScreen(game));
	}

	@Override
	public boolean touchDown(int x, int y, int pointer, int button) {
		
		WorldRenderer.cameraGUI.unproject(touchPoint.set(x, y, 0));
		if(moveLeft.contains(touchPoint.x, touchPoint.y)){
			WorldRenderer.moveLeft.setRegion(Assets.leftMove_press);
//			player.body.setLinearVelocity(-4, player.body.getLinearVelocity().y);
			isMoveLeft = true;
		}
		if(moveRight.contains(touchPoint.x, touchPoint.y)){
			WorldRenderer.moveRight.setRegion(Assets.rightMove_press);
//			player.body.setLinearVelocity(4, player.body.getLinearVelocity().y);
			isMoveRight = true;
		}
		if(moveJump.contains(touchPoint.x, touchPoint.y)){
			WorldRenderer.moveJump.setRegion(Assets.jumpMove_press);
//			player.setJumping(true);
			isJump = true;
		}
		Gdx.app.log("info", "down");
		return true;
	}

	@Override
	public boolean touchUp(int x, int y, int pointer, int button) {
		WorldRenderer.cameraGUI.unproject(touchPoint.set(x, y, 0));
		if(moveLeft.contains(touchPoint.x, touchPoint.y)){
			WorldRenderer.moveLeft.setRegion(Assets.leftMove);
			isMoveLeft = false;
		}
		if(moveRight.contains(touchPoint.x, touchPoint.y)){
			WorldRenderer.moveRight.setRegion(Assets.rightMove);
			isMoveRight = false;
		}
		if(moveJump.contains(touchPoint.x, touchPoint.y)){
			WorldRenderer.moveJump.setRegion(Assets.jumpMove);
//			player.setJumping(false);
			isJump = false;
		}
		return false;
	}


}
